#ifndef CircuitBASE_H
#define CircuitBASE_H

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include "node.h"

using namespace std;

class Circuit {
  public:
	/// Destructor
        ~Circuit();
	
	void write_prob(char *filename);
	void read_prob(char *filename);
	
	/// Return ith signal
        Signal* getSignal(int i) const {return signals[i];}
	 
	/// Return ith input of the Node
        Node* getInput(int i) const {return inputs[i];}
	
	/// Return ith output of the Node
        Node* getOutput(int i) const {return outputs[i];}
	
	/// Add a node to inputs of the Node
        bool addInput(Node *g) {inputs.push_back(g); return true;}

	/// Add a node to outputs of the Node
        bool addOutput(Node *g) {outputs.push_back(g); return true;}
	
        int inputSize(void) {return inputs.size();}
	
        int outputSize(void) {return outputs.size();}
	
	/// Return ith input of the Node
        Node* getGate(int i) const {return gates[i];}
        
        Node* getHGate(int i) const {return hgates[i];}
	
	/// Return ith output of the Node
        Node* getFlipflop(int i) const {return flipflops[i];}
         
	/// Add a node to inputs of the Node
        bool addGate(Node *g) {gates.push_back(g); return true;}

        bool addHGate(Node *g) {hgates.push_back(g); return true;}

	/// Add a node to outputs of the Node
        bool addFlipflop(Node *g) {flipflops.push_back(g); return true;}
	
        int gateSize(void) {return gates.size();}
	 
        int hgateSize(void) {return hgates.size();}

        int signalSize(void) {return signals.size();}
	
        int flipflopSize(void) {return flipflops.size();}
         
        Signal* addSignal(string const s);
         
	bool dumpHgates();

        bool dumpHgatesToFile();
  protected:

        /// inputs
        vector<Node*> inputs;
        /// outputs
        vector<Node*> outputs;
        /// gates
        vector<Node*> gates;
	
        vector<Node*> flipflops;
        
	vector<Signal*> signals;

        vector<Node*> hgates;
        
	// visibility stuff
	int TV,V0, V1;
  public:
	int noCff;
        int *idx_reflection;
        vector<Node*> criticalFFs;
};

#endif
